<template>
  <div ref="containerRef" class="flex flex-row flex-wrap">
    <div
      v-for="(item, index) in property.list"
      :key="index"
      :data-tooltip-index="index"
      class="menu-grid-item relative flex flex-col items-center cursor-pointer transition-opacity hover:opacity-80 active:opacity-60"
      :style="{ width: `${100 * (1 / property.column)}%` }"
      @click="handleItemClick(item, index)"
    >
      <!-- 右上角角标 -->
      <span
        v-if="item.badge?.show"
        class="absolute left-50% top-10px z-1 h-20px rounded-50% p-x-6px text-center text-12px leading-20px"
        :style="{
          color: item.badge.textColor,
          backgroundColor: item.badge.bgColor,
        }"
      >
        {{ item.badge.text }}
      </span>
      <!-- 图标：支持 URL 或图标类名 -->
      <el-image
        v-if="item.iconUrl && isImageUrl(item.iconUrl)"
        :style="{
          width: `${getIconSize(item)}px`,
          height: `${getIconSize(item)}px`,
        }"
        :src="item.iconUrl"
        fit="contain"
      />
      <i
        v-else-if="item.iconUrl"
        :class="item.iconUrl"
        :style="{
          fontSize: `${getIconSize(item)}px`,
          width: `${getIconSize(item)}px`,
          height: `${getIconSize(item)}px`,
        }"
      ></i>
      <span
        v-if="!shouldEnableTooltip(item)"
        class="menu-grid-title m-t-8px h-16px text-12px leading-16px"
        :style="{ color: item.titleColor }"
      >
        {{ item.title }}
      </span>
      <span
        class="m-t-6px h-12px text-10px leading-12px"
        :style="{ color: item.subtitleColor }"
      >
        {{ item.subtitle }}
      </span>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, onUpdated, onUnmounted, nextTick, watch } from 'vue'
import tippy from 'tippy.js'
import type { Instance } from 'tippy.js'
import 'tippy.js/dist/tippy.css'
import type { MenuGridProperty, MenuGridItemProperty } from './config'

defineOptions({ name: 'MenuGrid' })

const props = defineProps<{ property: MenuGridProperty }>()

/**
 * @description 容器元素引用
 */
const containerRef = ref<HTMLElement | null>(null)

/**
 * @description Tippy 实例
 */
const tippyInstances = ref<Map<number, Instance>>(new Map())

/**
 * @description 获取是否启用 tooltip
 * @param item 菜单项
 * @returns 是否启用
 */
const shouldEnableTooltip = (item: MenuGridItemProperty): boolean => {
  return item.enableTooltip ?? props.property.enableTooltip ?? false
}

/**
 * @description 获取 tooltip 内容
 * @param item 菜单项
 * @returns tooltip 内容（始终使用 title 的值）
 */
const getTooltipContent = (item: MenuGridItemProperty): string => {
  return item.title
}

/**
 * @description 初始化 tooltip
 */
const initTooltips = async () => {
  await nextTick()
  // 等待 DOM 完全更新
  await new Promise(resolve => setTimeout(resolve, 150))

  if (!containerRef.value) {
    console.warn('容器元素未找到')
    return
  }

  props.property.list.forEach((item, index) => {
    if (shouldEnableTooltip(item)) {
      // 通过 data 属性查找整个功能块元素
      const itemEl = containerRef.value?.querySelector(
        `.menu-grid-item[data-tooltip-index="${index}"]`
      ) as HTMLElement | null

      if (itemEl) {
        // 如果已存在实例，先销毁
        const existingInstance = tippyInstances.value.get(index)
        if (existingInstance) {
          existingInstance.destroy()
          tippyInstances.value.delete(index)
        }

        // 创建新的 tippy 实例
        try {
          const tooltipContent = getTooltipContent(item)
          if (tooltipContent) {
            const result = tippy(itemEl, {
              content: tooltipContent,
              placement: 'top',
              theme: 'light',
              arrow: true,
              delay: [100, 0],
              duration: [200, 150],
            })
            // tippy 可能返回单个实例或数组，需要处理
            const instance = Array.isArray(result) ? result[0] : result
            if (instance) {
              tippyInstances.value.set(index, instance as Instance)
            }
          }
        } catch (error) {
          console.error('初始化 tooltip 失败:', error, { item, index, itemEl })
        }
      } else {
        console.warn('功能块元素未找到:', { index, item })
      }
    }
  })
}

/**
 * @description 销毁 tooltip
 */
const destroyTooltips = () => {
  tippyInstances.value.forEach((instance, index) => {
    if (instance) {
      instance.destroy()
    }
    tippyInstances.value.delete(index)
  })
  tippyInstances.value.clear()
}

/**
 * @description 获取图标大小
 * @param item 菜单项
 * @returns 图标大小（px）
 */
const getIconSize = (item: MenuGridItemProperty): number => {
  return item.iconSize ?? props.property.iconSize ?? 28
}

const emit = defineEmits<{
  /**
   * @description 菜单项点击时触发
   */
  itemClick: [item: MenuGridItemProperty, index: number]
}>()

/**
 * @description 判断是否为图片 URL
 * @param url 图标 URL 或类名
 * @returns 是否为图片 URL
 */
const isImageUrl = (url: string): boolean => {
  return (
    url.startsWith('http://') ||
    url.startsWith('https://') ||
    url.startsWith('data:') ||
    url.startsWith('/') ||
    url.includes('.')
  )
}

/**
 * @description 处理菜单项点击
 * @param item 菜单项
 * @param index 索引
 */
const handleItemClick = (item: MenuGridItemProperty, index: number) => {
  emit('itemClick', item, index)

  if (item.url) {
    // 如果是外部链接
    if (item.url.startsWith('http://') || item.url.startsWith('https://')) {
      window.open(item.url, '_blank')
    } else {
      // 内部路由跳转（需要根据项目路由配置调整）
      console.log('导航到:', item.url)
    }
  }
}

onMounted(() => {
  initTooltips()
})

onUpdated(() => {
  // 组件更新后，检查是否需要初始化新的 tooltip
  initTooltips()
})

onUnmounted(() => {
  destroyTooltips()
})

// 监听列表变化，重新初始化 tooltip
watch(
  () => props.property.list,
  () => {
    destroyTooltips()
    nextTick(() => {
      initTooltips()
    })
  },
  { deep: true, immediate: false }
)

// 监听 enableTooltip 变化
watch(
  () => [
    props.property.enableTooltip,
    props.property.list.map(item => item.enableTooltip),
  ],
  () => {
    destroyTooltips()
    nextTick(() => {
      initTooltips()
    })
  },
  { deep: true }
)
</script>

<style scoped lang="scss"></style>
